package com.jyw.business.ast.service.impl;

import java.util.List;
import java.util.stream.Collectors;

import com.jyw.business.ast.constant.AstRelationConstant;
import com.jyw.business.ast.domain.AstDealRelation;
import com.jyw.business.ast.domain.AstInfo;
import com.jyw.business.ast.domain.AstTransfer;
import com.jyw.business.ast.domain.dto.web.*;
import com.jyw.business.ast.domain.vo.web.AstBorrowDetailVo;
import com.jyw.business.ast.domain.vo.web.AstBorrowPageVo;
import com.jyw.business.ast.domain.vo.web.BorrowAstVo;
import com.jyw.business.ast.service.IAstDealRelationService;
import com.jyw.business.ast.service.IAstInfoService;
import com.jyw.common.exception.ServiceException;
import com.jyw.common.utils.DateUtils;
import com.jyw.common.utils.SecurityUtils;
import com.jyw.common.utils.bean.BeanUtils;
import com.jyw.system.utils.ConversionUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import com.jyw.business.ast.mapper.AstBorrowMapper;
import com.jyw.business.ast.domain.AstBorrow;
import com.jyw.business.ast.service.IAstBorrowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 资产-借用信息Service业务层处理
 * 
 * @author system
 * @date 2023-10-19
 */
@Service
public class AstBorrowServiceImpl extends ServiceImpl<AstBorrowMapper,AstBorrow> implements IAstBorrowService
{
    @Resource
    private AstBorrowMapper astBorrowMapper;

    @Resource
    private IAstDealRelationService relationService;

    @Resource
    private IAstInfoService infoService;

    /**
     * 查询资产-借用信息
     * 
     * @param id 资产-借用信息主键
     * @return 资产-借用信息
     */
    @Override
    public AstBorrow selectAstBorrowById(Long id)
    {
        return astBorrowMapper.selectAstBorrowById(id);
    }

    /**
     * 查询资产-借用信息列表
     * 
     * @param astBorrow 资产-借用信息
     * @return 资产-借用信息
     */
    @Override
    public List<AstBorrow> selectAstBorrowList(AstBorrow astBorrow)
    {
        return astBorrowMapper.selectAstBorrowList(astBorrow);
    }

    /**
     * 新增资产-借用信息
     * 
     * @param astBorrow 资产-借用信息
     * @return 结果
     */
    @Override
    public int insertAstBorrow(AstBorrow astBorrow)
    {
        astBorrow.setCreateTime(DateUtils.getNowDate());
        return astBorrowMapper.insertAstBorrow(astBorrow);
    }

    /**
     * 修改资产-借用信息
     * 
     * @param astBorrow 资产-借用信息
     * @return 结果
     */
    @Override
    public int updateAstBorrow(AstBorrow astBorrow)
    {
        return astBorrowMapper.updateAstBorrow(astBorrow);
    }

    /**
     * 批量删除资产-借用信息
     * 
     * @param ids 需要删除的资产-借用信息主键
     * @return 结果
     */
    @Override
    public int deleteAstBorrowByIds(Long[] ids)
    {
        return astBorrowMapper.deleteAstBorrowByIds(ids);
    }

    /**
     * 删除资产-借用信息信息
     * 
     * @param id 资产-借用信息主键
     * @return 结果
     */
    @Override
    public int deleteAstBorrowById(Long id)
    {
        return astBorrowMapper.deleteAstBorrowById(id);
    }

    @Override
    public List<AstBorrowPageVo> borrowPage(AstBorrowPageDto dto) {
        dto.setCreateEndTime(DateUtils.toDateLastTime(dto.getCreateEndTime()));
        dto.setInDept(SecurityUtils.getDeptId());
        List<AstBorrowPageVo> list = astBorrowMapper.page(dto);
        return ConversionUtil.conversionList(list,AstBorrowPageVo.class);
    }

    @Override
    public AstBorrowDetailVo borrowDetail(Long id) {
        AstBorrow borrow = getById(id);
        AstBorrowDetailVo detailVo = new AstBorrowDetailVo(borrow);
        List<BorrowAstVo> list = relationService.borrowRelation(id);
        detailVo.setList(list);
        return ConversionUtil.conversion(detailVo,AstBorrowDetailVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void borrow(AstBorrowDto dto) {
        AstBorrow borrow = dto.buildBorrow();
        //保存出借信息
        save(borrow);
        List<AstDealRelation> list = dto.buildRelation(borrow);
        //保存出借资产关系
        relationService.saveBatch(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revoke(Long id) {
        AstBorrow borrow = getById(id);
        if(ObjectUtils.isEmpty(borrow)){
            throw new ServiceException("借用申请,不存在");
        }
        if(!borrow.getAuditState().equals("0")){
            throw new ServiceException("已审核,无法撤销");
        }
        //删除关系
        relationService
                .lambdaUpdate()
                .eq(AstDealRelation::getType, AstRelationConstant.BORROW)
                .eq(AstDealRelation::getBusinessId,id)
                .remove();
        //删除借用信息表
        removeById(id);
    }

    @Override
    public List<AstBorrowPageVo> borrowAuditPage(AstBorrowAuditPageDto dto) {
        AstBorrowPageDto param = new AstBorrowPageDto();
        BeanUtils.copyProperties(dto,param);
        param.setCreateEndTime(DateUtils.toDateLastTime(dto.getCreateEndTime()));
        param.setOutDept(SecurityUtils.getDeptId());
        List<AstBorrowPageVo> list = astBorrowMapper.page(param);
        return ConversionUtil.conversionList(list,AstBorrowPageVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pass(List<Long> list) {
        list = lambdaQuery()
                .in(AstBorrow::getId,list)
                .eq(AstBorrow::getAuditState,0)
                .list().stream().map(AstBorrow::getId).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(list)){
            //查询所有资产
            List<AstDealRelation> relationList = relationService
                    .lambdaQuery()
                    .eq(AstDealRelation::getType, AstRelationConstant.BORROW)
                    .in(AstDealRelation::getBusinessId, list)
                    .list();
            //封装资产使用科室修改信息
            List<AstInfo> astUpdateList = relationList.stream().map(data -> {
                AstInfo info = new AstInfo();
                info.setId(data.getAstId());
                info.setUseDept(data.getInDept());
                return info;
            }).collect(Collectors.toList());
            //修改资产使用科室
            infoService.updateBatchById(astUpdateList);
            //批量修改转移信息
            lambdaUpdate()
                    .in(AstBorrow::getId,list)
                    .set(AstBorrow::getAuditUser,SecurityUtils.getUserId())
                    //设置审批状态为通过
                    .set(AstBorrow::getAuditState,"2")
                    //设置状态为待归还
                    .set(AstBorrow::getState,"3")
                    .update();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditRejected(AstRejectedDto dto) {
        lambdaUpdate()
                .eq(AstBorrow::getId,dto.getId())
                //设置审核状态为驳回
                .set(AstBorrow::getAuditState,"1")
                //设置备注
                .set(AstBorrow::getAuditRemark,dto.getRemark())
                //设置状态为驳回
                .set(AstBorrow::getState,"2")
                .update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void borrowReturn(AstBorrowReturnDto dto) {
        AstBorrow borrow = getById(dto.getId());
        if(ObjectUtils.isEmpty(borrow)){
            throw new ServiceException("借用信息不存在");
        }
        if(!borrow.getState().equals("3")){
            throw new ServiceException("非待归还状态");
        }
        //将资产还原
        List<AstDealRelation> list = relationService.lambdaQuery()
                .eq(AstDealRelation::getType, AstRelationConstant.BORROW)
                .eq(AstDealRelation::getBusinessId, dto.getId())
                .list();
        list.forEach(data->{
            infoService.updateById(new AstInfo(){{setId(data.getAstId());setId(data.getOutDept());}});
        });
        //设置归还信息
        updateById(dto.buildBorrow());
    }
}
